if(!jsx3.lang.Class.forName("tibco.admin.deployment.saList.ServiceAssemblyList")) {

    /**
     **/
    jsx3.lang.Package.definePackage("tibco.admin.deployment.saList", function (saListp) {
    });

    /**
     **/
    jsx3.lang.Class.defineClass("tibco.admin.deployment.saList.ServiceAssemblyList",
            jsx3.lang.Object,
            null,
            function(saList) {
                // handler for this project and GUI interface.
                saList.server = tibco.admin.Main.getServer();
                saList.rootNode = null;

                // the environment id and name should be get by subscribe message.
                saList.evnEntityID = null;
                saList.environment = null;
                // the current selected entity ids.
                saList.selection = new jsx3.util.List(0);

                /**
                 * Called when after deserialize time.
                 */
                saList.onAfterDeserialize = function(rootNode) {
                    var me = saList;
                    rootNode.handler = me;
                    saList.rootNode = rootNode;
                    saList.loadPermissionButtons();
                    saList.subscribeAll();
                    saList.callgetAllServiceAssemblies();
                };

                /**
                 * Called when destroy event fired.
                 */
                saList.onDestroy = function() {
                    saList.selection.clear();
                    saList.unsubscribeAll();
                };

                /**
                 * Subscribe all relative events with current component.
                 */
                saList.subscribeAll = function() {
                    tibco.admin.PubSub.subscribe(tibco.admin.deployment.EventID.ENVIRONMENT_SELECTED,
                            saList.onEnvironmentSelected);
                    tibco.admin.PubSub.subscribe(tibco.admin.deployment.saList.EventID.SERVICEASSEMBLY_ADD_SUCCESSFUL,
                            saList.callgetAllServiceAssemblies);
                    tibco.admin.PubSub.subscribe(tibco.admin.deployment.sa.updateSA.EventID.SERVICEASSEMBLY_UPDATED,
                            saList.callgetAllServiceAssemblies);
                };

                /**
                 * Unsubscribe all relative events with current component.
                 */
                saList.unsubscribeAll = function() {
                    tibco.admin.PubSub.unsubscribe(tibco.admin.deployment.EventID.ENVIRONMENT_SELECTED,
                            saList.onEnvironmentSelected);
                    tibco.admin.PubSub.unsubscribe(tibco.admin.deployment.saList.EventID.SERVICEASSEMBLY_ADD_SUCCESSFUL,
                            saList.callgetAllServiceAssemblies);
                    tibco.admin.PubSub.unsubscribe(tibco.admin.deployment.sa.updateSA.EventID.SERVICEASSEMBLY_UPDATED,
                            saList.callgetAllServiceAssemblies);
                };

                /**
                 * Load permission buttons from a serialize file
                 */
                saList.loadPermissionButtons = function() {
                    var root = saList.rootNode;
                    var domNode = root.getDescendantOfName("panePermissions_41");
                    saList.permissions = tibco.admin.Main.loadUIResource(domNode, "tibco.admin",
                            "tibco/admin/enterpriseAssets/userMgt/window/permissions/ui/setPermissions.xml", true);
                    var mtxServiceAssemblyList = root.getDescendantOfName("mtxServiceAssemblyList_41");
                    saList.permissions.initialize("ServiceAssembly", "jsxid", "name", mtxServiceAssemblyList);
                };

                /**
                 * Called when environment select-box fire a select event
                 * Have been subscribe as a callback function.
                 */
                saList.onEnvironmentSelected = function(objEvent) {
                    saList.evnEntityID = objEvent.envID;
                    saList.environment = objEvent.envName;
                    saList.selection.clear();
                };

                /**
                 * Get all service assembilies form server
                 */
                saList.callgetAllServiceAssemblies = function() {
                    var objService = tibco.admin.Main.loadService("tibco.admin",
                            "tibco/admin/deployment/saList/rules/getAllServiceAssemblies.xml",
                            "getAllServiceAssemblies");

                    objService.evnEntityID = saList.evnEntityID;
                    objService.setEndpointURL(tibco.admin.util.ServiceHelper.getDeploymentEndpointURL());

                    objService.subscribe(jsx3.net.Service.ON_SUCCESS, saList.ongetAllServiceAssembliesSuccess);
                    objService.subscribe(jsx3.net.Service.ON_ERROR, saList.ongetAllServiceAssembliesError);
                    objService.subscribe(jsx3.net.Service.ON_INVALID, saList.ongetAllServiceAssembliesInvalid);
                    objService.doCall();
                };

                saList.ongetAllServiceAssembliesSuccess = function(objEvent) {
                    var root = saList.rootNode;
                    var mtxServiceAssemblyList = root.getDescendantOfName("mtxServiceAssemblyList_41");

                    // hide set permissions buttons first
                    saList.hideSetPermissions();
                    // restore the selected item which is selected before.
                    var selectedSize = saList.selection.size();
                    for (var i = 0; i < selectedSize; i++)
                    {
                        mtxServiceAssemblyList.selectRecord(saList.selection.get(i));
                    }
                    mtxServiceAssemblyList.repaint();

                    // publish selection again, upade buttons status
                    nodes = mtxServiceAssemblyList.getSelectedNodes();
                    if (nodes.size() == 1)
                    {
                        saList.publishSASelectedEvent(nodes.get(0));
                    }
                    else
                    {
                        saList.publishSASelectedEvent(null);
                    }
                    saList.updateButtonStates(nodes);
                    saList.permissions.switchPermissionBtn();
                };

                saList.ongetAllServiceAssembliesError = function(objEvent) {
                    tibco.admin.util.Log.DEPLOYMENT.error("Error , The service call getAllServiceAssemblies failed.");
                    var request = objEvent.target.getRequest()
                    if(request) {
                        var myStatus = request.getStatus();
                        tibco.admin.util.Log.DEPLOYMENT.error("The HTTP Status code for service call getAllServiceAssemblies is: " + myStatus);
                        tibco.admin.util.Log.DEPLOYMENT.error("The response text for service call getAllServiceAssemblies is: " + request.getResponseText());
                        tibco.admin.util.Log.DEPLOYMENT.error("The response xml for service call getAllServiceAssemblies is: " + request.getResponseXML());
                    }
                    else {
                        tibco.admin.util.Log.DEPLOYMENT.error("Error, request for service call getAllServiceAssemblies is null")
                    }
                };

                saList.ongetAllServiceAssembliesInvalid = function(objEvent) {
                    tibco.admin.util.Log.DEPLOYMENT.error("Invalid", "The following message node just failed validation:\n\n" + objEvent);
                };

                /**
                 * Call removeServiceAssemblies operation to the web service.
                 */
                saList.callremoveServiceAssemblies = function(forceAction) {
                    var objService = tibco.admin.Main.loadService("tibco.admin",
                            "tibco/admin/deployment/saList/rules/removeServiceAssemblies.xml",
                            "removeServiceAssemblies");

                    objService.envEntityID = saList.evnEntityID;
                    objService.forceAction = forceAction;
                    objService.setEndpointURL(tibco.admin.util.ServiceHelper.getDeploymentEndpointURL());

                    objService.subscribe(jsx3.net.Service.ON_SUCCESS, saList.onremoveServiceAssembliesSuccess);
                    objService.doCall();
                };

                saList.onremoveServiceAssembliesSuccess = function(objEvent) {
                    saList.hideSetPermissions();
                    saList.callgetAllServiceAssemblies();
                };

                saList.hideSetPermissions = function() {
                    saList.permissions.setPermissionBtn.setDisplay(jsx3.gui.Block.DISPLAYNONE, true);
                    saList.permissions.addPermissionBtn.setDisplay(jsx3.gui.Block.DISPLAYNONE, true);
                };

                saList.onremoveServiceAssembliesError = function(objEvent) {
                };

                saList.onremoveServiceAssembliesInvalid = function(objEvent) {
                };

                /**
                 * Call deployServiceAssemblies operation to the web service.
                 */
                saList.calldeployServiceAssemblies = function() {
                    var objService = tibco.admin.Main.loadService("tibco.admin",
                            "tibco/admin/deployment/saList/rules/deployServiceAssemblies.xml",
                            "deployServiceAssemblies");

                    objService.envEntityID = saList.evnEntityID;
                    objService.setEndpointURL(tibco.admin.util.ServiceHelper.getDeploymentEndpointURL());

                    objService.subscribe(jsx3.net.Service.ON_SUCCESS, saList.ondeployServiceAssembliesSuccess);
                    objService.doCall();
                };

                saList.ondeployServiceAssembliesSuccess = function(objEvent) {
                    saList.callgetAllServiceAssemblies();
                };

                saList.ondeployServiceAssembliesError = function(objEvent) {
                };

                saList.ondeployServiceAssembliesInvalid = function(objEvent) {
                };

                /**
                 * Call redeployServiceAssemblies operation to the web service.
                 */
                saList.callredeployServiceAssemblies = function() {
                    var objService = tibco.admin.Main.loadService("tibco.admin",
                            "tibco/admin/deployment/saList/rules/redeployServiceAssemblies.xml",
                            "redeployServiceAssemblies");

                    objService.envEntityID = saList.evnEntityID;
                    objService.setEndpointURL(tibco.admin.util.ServiceHelper.getDeploymentEndpointURL());

                    objService.subscribe(jsx3.net.Service.ON_SUCCESS, saList.onredeployServiceAssembliesSuccess);
                    objService.doCall();
                };

                saList.onredeployServiceAssembliesSuccess = function(objEvent) {
                    saList.callgetAllServiceAssemblies();
                };

                saList.onredeployServiceAssembliesError = function(objEvent) {
                };

                saList.onredeployServiceAssembliesInvalid = function(objEvent) {
                };

                /**
                 * Call undeployServiceAssemblies operation to the web service.
                 */
                saList.callundeployServiceAssemblies = function() {
                    var objService = tibco.admin.Main.loadService("tibco.admin",
                            "tibco/admin/deployment/saList/rules/undeployServiceAssemblies.xml",
                            "undeployServiceAssemblies");

                    objService.envEntityID = saList.evnEntityID;
                    objService.setEndpointURL(tibco.admin.util.ServiceHelper.getDeploymentEndpointURL());

                    objService.subscribe(jsx3.net.Service.ON_SUCCESS, saList.onundeployServiceAssembliesSuccess);
                    objService.doCall();
                };

                saList.onundeployServiceAssembliesSuccess = function(objEvent) {
                    saList.callgetAllServiceAssemblies();
                };

                saList.onundeployServiceAssembliesError = function(objEvent) {
                };

                saList.onundeployServiceAssembliesInvalid = function(objEvent) {
                };

                /**
                 * Call startServiceAssemblies operation to the web service.
                 */
                saList.callstartServiceAssemblies = function() {
                    var objService = tibco.admin.Main.loadService("tibco.admin",
                            "tibco/admin/deployment/saList/rules/startServiceAssemblies.xml",
                            "startServiceAssemblies");

                    objService.envEntityID = saList.evnEntityID;
                    objService.setEndpointURL(tibco.admin.util.ServiceHelper.getDeploymentEndpointURL());

                    objService.subscribe(jsx3.net.Service.ON_SUCCESS, saList.onstartServiceAssembliesSuccess);
                    objService.doCall();
                };

                saList.onstartServiceAssembliesSuccess = function(objEvent) {
                    saList.callgetAllServiceAssemblies();
                };

                saList.onstartServiceAssembliesError = function(objEvent) {
                };

                saList.onstartServiceAssembliesInvalid = function(objEvent) {
                };

                /**
                 * Call startServiceAssemblies operation to the web service.
                 */
                saList.callstopServiceAssemblies = function() {
                    var objService = tibco.admin.Main.loadService("tibco.admin",
                            "tibco/admin/deployment/saList/rules/stopServiceAssemblies.xml",
                            "stopServiceAssemblies");

                    objService.envEntityID = saList.evnEntityID;
                    objService.setEndpointURL(tibco.admin.util.ServiceHelper.getDeploymentEndpointURL());

                    objService.subscribe(jsx3.net.Service.ON_SUCCESS, saList.onstopServiceAssembliesSuccess);
                    objService.doCall();
                };

                saList.onstopServiceAssembliesSuccess = function(objEvent) {
                    saList.callgetAllServiceAssemblies();
                };

                saList.onstopServiceAssembliesError = function(objEvent) {
                };

                saList.onstopServiceAssembliesInvalid = function(objEvent) {
                };

                /**
                 * Call this method when user selected the service assembly item on the list.
                 * Do Message publish logic.
                 */
                saList.mtxServiceAssemblyList_41_OnSelect = function() {
                    try {
                        var mtx = saList.rootNode.getDescendantOfName("mtxServiceAssemblyList_41");
                        if(saList.ignoreSelects) {
                            var cacheDoc = mtx.getXML();
                            if(cacheDoc) {
                                var recordIter = cacheDoc.getXML().selectNodes("//record[@jsxselected='1']");
                                while(recordIter.hasNext()) {
                                    var record = recordIter.next();
                                    record.setAttribute("jsxselected", 0);
                                }
                                var iter = saList.selection.iterator();
                                while(iter.hasNext()) {
                                    var jsxid = iter.next();
                                    var record = cacheDoc.getXML().selectSingleNode("//record[@jsxid='" + jsxid + "']");
                                    if(record) {
                                        record.setAttribute("jsxselected", 1);
                                    }
                                }
                            }
                            saList.updateButtonStates(saList.rootNode.getDescendantOfName("mtxServiceAssemblyList_41").getSelectedNodes());
                            mtx.repaint();
                        }
                        else {
                            saList.selection.clear();
                            var nodes = mtx.getSelectedNodes();
                            saList.updateButtonStates(nodes);
                            var selectionSize = nodes.size();
                            for(var i = 0; i < selectionSize; i++) {
                                saList.selection.add(nodes.getItem(i).getAttribute('jsxid'));
                            }
                            if (selectionSize == 1)
                            {
                                saList.publishSASelectedEvent(nodes.getItem(0));
                            }
                            else
                            {
                                saList.publishSASelectedEvent(null);
                            }
                            saList.permissions.switchPermissionBtn();
                        }
                    }
                    catch(ex) {
                        jsx3.log(ex);
                        tibco.admin.Main.logException(ex);
                    }
                };

                saList.updateButtonStates = function(list) {
                    var count = list.size();
                    var notDeployed = 0
                    var deployed = 0
                    var deployedWithError = 0
                    var running = 0
                    var runningWithError = 0
                    var unknown = 0;
                    var notOwner = 0;
                    var redeployable = 0;
                    var iter = list.iterator();
                    var deployable = 0;
                    while(iter.hasNext()) {
                        var node = iter.next();
                        var saState = node.getAttribute("saState");
                        if (node.getAttribute("deployable") == "true") {
                            deployable++;
                        }

                        if(node.getAttribute("hasOwner") != "true") {
                            notOwner++;
                        }
                        if(node.getAttribute("deploymentInfo") == "REDEPLOYABLE") {
                            redeployable++;
                        }
                        switch(saState) {
                            case "NOTDEPLOYED":
                                notDeployed++;
                                break;
                            case "DEPLOYED":
                                deployed++;
                                break;
                            case "DEPLOYED_WITH_ERROR":
                                deployedWithError++;
                                break;
                            case "RUNNING":
                                running++;
                                break;
                            case "RUNNING_WITH_ERROR":
                                runningWithError++;
                                break;
                            case "UNKNOWN":
                                unknown++;
                                break;
                            default:
                                unknown++;
                                break;
                        }
                    }
                    tibco.admin.Main.getServer().getJSXByName("btnDelete_41").setEnabled(((notOwner == 0) && (count > 0) && !saList.ignoreSelects) ? jsx3.gui.Form.STATEENABLED : jsx3.gui.Form.STATEDISABLED, true);
                    tibco.admin.Main.getServer().getJSXByName("btnDeploy_41").setEnabled((((notDeployed + unknown) == count) && (deployable == count) && (count > 0)) ? jsx3.gui.Form.STATEENABLED : jsx3.gui.Form.STATEDISABLED, true);
                    tibco.admin.Main.getServer().getJSXByName("btnRedeploy_41").setEnabled(((redeployable == count) && (count > 0)) ? jsx3.gui.Form.STATEENABLED : jsx3.gui.Form.STATEDISABLED, true);
                    tibco.admin.Main.getServer().getJSXByName("btnUndeploy_41").setEnabled((((running + deployed + deployedWithError + unknown) == count) && (count > 0)) ? jsx3.gui.Form.STATEENABLED : jsx3.gui.Form.STATEDISABLED, true);
                    tibco.admin.Main.getServer().getJSXByName("btnStart_41").setEnabled((((deployed + deployedWithError + unknown) == count) && (count > 0)) ? jsx3.gui.Form.STATEENABLED : jsx3.gui.Form.STATEDISABLED, true);
                    tibco.admin.Main.getServer().getJSXByName("btnStop_41").setEnabled((((running + runningWithError + unknown) == count) && (count > 0)) ? jsx3.gui.Form.STATEENABLED : jsx3.gui.Form.STATEDISABLED, true);
                }

                /**
                 * Used for publish detail information of selected item.
                 */
                saList.publishSASelectedEvent = function(recordNode) {
                    var msg = new Object();
                    msg.envEntityID = saList.evnEntityID;

                    if(recordNode) {
                        msg.entityID = recordNode.getAttribute("jsxid");
                        msg.name = recordNode.getAttribute("name");
                        msg.description = recordNode.getAttribute("description");
                        msg.archiveFile = recordNode.getAttribute("archiveFileLocation");
                        msg.packagedBy = recordNode.getAttribute("packagedBy");
                        msg.contact = recordNode.getAttribute("contact");
                        msg.namespace = recordNode.getAttribute("targetNamespace");
                        msg.status = recordNode.getAttribute("saState");
                        msg.exposeEndpoints = recordNode.getAttribute("exposeEndpoints");
                        msg.localProviders = recordNode.getAttribute("useLocalProviders");
                        msg.hasEdit = recordNode.getAttribute("hasEdit");
                        msg.hasOwner = recordNode.getAttribute("hasOwner");
                    }
                    else
                    {
                        msg.entityID = null;
                    }

                    // message indentifier
                    msg.subject = tibco.admin.deployment.saList.EventID.SERVICEASSEMBLY_ROW_SELECTED;
                    tibco.admin.PubSub.publish(msg);
                };

                /**
                 * Check whether the specified matrix has been selected.
                 */
                saList.isItemSelected = function(strMtxName) {
                    var root = saList.rootNode;
                    var selectedNodes = root.getDescendantOfName(strMtxName).getSelectedNodes();
                    return selectedNodes.size() > 0;
                };

                /**
                 * Call this method when "Delete" button clicked.
                 */
                saList.btnDelete_41_OnClick = function() {
                    if(!saList.isItemSelected("mtxServiceAssemblyList_41")) return;

                    var forceDelete = APP.tibco.admin.getBodyBlock().load("tibco/admin/deployment/saList/ui/forceDelete.xml");
                    forceDelete.setCallback(
                            function(dialog) {
                                saList.callremoveServiceAssemblies(dialog.confirmed);
                                dialog.doClose();
                            },
                            function(dialog) {
                                dialog.doClose();
                            });
                };

                /**
                 * Call this method when "Deploy" button clicked.
                 */
                saList.btnDeploy_41_OnClick = function() {
                    if(!saList.isItemSelected("mtxServiceAssemblyList_41")) return;

                    saList.calldeployServiceAssemblies();
                };

                /**
                 * Call this method when "Redeploy" button clicked.
                 */
                saList.btnRedeploy_41_OnClick = function() {
                    if(!saList.isItemSelected("mtxServiceAssemblyList_41")) return;

                    saList.callredeployServiceAssemblies();
                };

                /**
                 * Call this method when "Undeploy" button clicked.
                 */
                saList.btnUndeploy_41_OnClick = function() {
                    if(!saList.isItemSelected("mtxServiceAssemblyList_41")) return;

                    saList.callundeployServiceAssemblies();
                };

                /**
                 * Call this method when "Start" button clicked.
                 */
                saList.btnStart_41_OnClick = function() {
                    if(!saList.isItemSelected("mtxServiceAssemblyList_41")) return;

                    saList.callstartServiceAssemblies();
                };

                /**
                 * Call this method when "Stop" button clicked.
                 */
                saList.btnStop_41_OnClick = function() {
                    if(!saList.isItemSelected("mtxServiceAssemblyList_41")) return;

                    saList.callstopServiceAssemblies();
                };

                /**
                 * Call this method when "Refresh" button clicked.
                 */
                saList.btnRefresh_41_OnClick = function() {
                    saList.callgetAllServiceAssemblies();
                };

                /**
                 * Call this method when mouse move on any matix cell.
                 */
                saList.mtxServiceAssemblyList_41_Spyglass = function(strRECORDID, objCOLUMN) {
                    var root = saList.rootNode;
                    var mtxServiceAssemblyList = root.getDescendantOfName("mtxServiceAssemblyList_41");
                    var recordNode = mtxServiceAssemblyList.getRecordNode(strRECORDID);

                    if(objCOLUMN.getName() == "mcDeployable_41")
                    {
                        var deployable = recordNode.getAttribute("deployable");
                        if(deployable == "false")
                        {
                            return "<div style='width:300;'><b>" +
                                   saList.server.getDynamicProperty("@@DeployableMessage_41") +
                                   "</b><div>" + recordNode.getAttribute("deployableMessage").replace(/\n/g, "<br>") + "</div></div>";
                        }
                    }

                    if(objCOLUMN.getName() == "mcState_41")
                    {
                        var saState = recordNode.getAttribute("saState");
                        if(saState == "DEPLOYED_WITH_ERROR" || saState == "RUNNING_WITH_ERROR")
                        {
                            return "<div style='width:300;'><b>" +
                                   saList.server.getDynamicProperty("@@saErrorStateSummary_41") +
                                   "</b><div>" + recordNode.getAttribute("stateErrorSummary").replace(/\n/g, "<br>") + "</div></div>";
                        }
                    }

                };

                /**
                 * Call this method when clicked the "No" text in deployable cell.
                 */
                saList.popupDeployableMessage = function(id) {
                    var root = saList.rootNode;
                    var deployableMessage = root.getDescendantOfName("mtxServiceAssemblyList_41").
                            getRecordNode(id).getAttribute("deployableMessage");
                    tibco.admin.Main.alert(tibco.admin.Main.getServer().getDynamicProperty("@@DeployableMessageTitle_41"), deployableMessage);
                };

                saList.beginEdit = function() {
                    saList.ignoreSelects = true;
                    saList.updateButtonStates(saList.rootNode.getDescendantOfName("mtxServiceAssemblyList_41").getSelectedNodes());
                }

                saList.endEdit = function() {
                    saList.ignoreSelects = false;
                    saList.updateButtonStates(saList.rootNode.getDescendantOfName("mtxServiceAssemblyList_41").getSelectedNodes());
                }
            });
}